Date.prototype.format=function(fmt){ 
	if(!this.getTime()) return "";
	let o={"M+": this.getMonth() + 1,"d+": this.getDate(),"H+": this.getHours(),"m+": this.getMinutes(),"s+": this.getSeconds(),"q+": Math.floor((this.getMonth() + 3) / 3),"S": this.getMilliseconds()};
	if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); 
	for (let k in o) if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
	return fmt; 
};
Date.prototype.formatShow=function(fmt){
	if(!this.getTime()) return "";
	let dateString=this.format(fmt);
	let str="";
	let date=new Date();
	if(date.getFullYear()==parseInt(dateString.substring(0,4))){
		if(date.getMonth()+1==parseInt(dateString.substring(5,7))){
			if(date.getDate()==parseInt(dateString.substring(8,10))){
				str="今天";
			}else if(date.getDate()-parseInt(dateString.substring(8,10))==1){
				str="昨天";
			}else if(date.getDate()-parseInt(dateString.substring(8,10))==-1){
				str="明天";
			}else if(date.getDate()-parseInt(dateString.substring(8,10))==2){
				str="前天";
			}else if(date.getDate()-parseInt(dateString.substring(8,10))==-2){
				str="后天";
			}else{
				str=parseInt(dateString.substring(5,7))+"月"+parseInt(dateString.substring(8,10))+"日";
			}
		}else{
			str=parseInt(dateString.substring(5,7))+"月"+parseInt(dateString.substring(8,10))+"日";
		}
		str=str+dateString.substring(10);
	}else{
		str=parseInt(dateString.substring(0,4))+"年"+parseInt(dateString.substring(5,7))+"月"+parseInt(dateString.substring(8,10))+"日"+dateString.substring(10);
	}
	return str;
};
Array.prototype.indexOf = function(val) {
	for (let i = 0; i < this.length; i++) {
		if (this[i] == val) return i;
	}
	return -1;
};
Array.prototype.remove = function(val) {
	let index = this.indexOf(val);
	if (index > -1) {
		this.splice(index, 1);
	}
};
function deepMerge(target,obj) {
    for(var key in obj){
        if (target[key] && obj[key] && typeof obj[key] === 'object') {
            obj[key]=deepMerge(target[key],obj[key])  // 递归
        }
    }
    return Object.assign(target,obj);
}
function formatNumber(num, pattern) {
    if(null==num || undefined==num) return "";
    if(pattern.substring(0,pattern.length-1)+"%"==pattern){
        return formatNumber(num*100.0,pattern.substring(0,pattern.length-1))+"%";
    }
	let fmtarr = pattern ? pattern.split('.') : [''];
	let decimals = (fmtarr.length > 1 ? fmtarr[1].length : 0);
	num = Math.round(num * Math.pow(10, decimals)) / Math.pow(10, decimals);
	let strarr = num ? num.toString().split('.') : ['0'];
	let retstr = '';
	let str=strarr[0],fmt=fmtarr[0],i=str.length-1,comma = false;
	for (let f = fmt.length - 1; f >= 0; f--) {
		switch (fmt.substr(f, 1)) {
			case '#':
				if (i >= 0) retstr = str.substr(i--, 1) + retstr; 
				break;
			case '0':
				if (i >= 0) retstr = str.substr(i--, 1) + retstr; 
				else	retstr = '0' + retstr;
				break;
			case ',':
				comma = true;
				retstr = ',' + retstr;
				break;
		}
	}
	if (i >= 0) {
		if (comma) {
			let l = str.length;
			for (; i >= 0; i--) {
				retstr = str.substr(i, 1) + retstr;
				if (i > 0 && ((l - i) % 3) == 0) retstr = ',' + retstr;
			}
		}else retstr = str.substr(0, i + 1) + retstr;
	}
	retstr = retstr + '.';
	str = strarr.length > 1 ? strarr[1] : '';
	fmt = fmtarr.length > 1 ? fmtarr[1] : '';
	i = 0;
	for (let f = 0; f < fmt.length; f++) {
		switch (fmt.substr(f, 1)) {
			case '#':
				if (i < str.length) retstr += str.substr(i++, 1);
				break;
			case '0':
				if (i < str.length) retstr += str.substr(i++, 1);
				else retstr += '0';
				break;
		}
	}
	return retstr.replace(/^,+/, '').replace(/^-,+/, '-').replace(/\.$/, '');
}

var mo={
    theme:{token:{}},
	system:{},//系统设置
	admin:{},//用户信息
	assist:{},//外协登录信息
	orgGroup:{},//部门信息
	setting:{},//用户设置
	powers:{},//权限信息
	pages:{},
	pageV3s:{},
	charts:{},
	dictLoad:{},dictReload:{},dictMap:{},dictOpts:{},dictTreeOpts:{},
	setTheme:function(){
        mo.theme={token:{
            colorPrimary:mo.setting.color||'#0066ff',
            colorSuccess:mo.setting.successColor||'#44cc00',
            colorWarning:mo.setting.warningColor||'#ff9900',
            colorError:mo.setting.errorColor||'#ff3300',
            colorInfo:mo.setting.infoColor,
            borderRadius:mo.setting.radius||3,
            borderRadiusSM:mo.setting.radius||3,
            borderRadiusXS:mo.setting.radius||3
        }};
        if(!mo.theme.token['colorInfo']) mo.theme.token['colorInfo']=mo.theme.token['colorPrimary'];
        mo.theme['algorithm']=mo.setting.theme?antd.theme.darkAlgorithm:antd.theme.defaultAlgorithm;
        document.body.style.setProperty('--colorPrimary', this.theme.token.colorPrimary);
        document.body.style.setProperty('--colorPrimary2', this.theme.token.colorPrimary+'22');
        document.body.style.setProperty('--colorPrimary4', this.theme.token.colorPrimary+'44');
        document.body.style.setProperty('--colorPrimary8', this.theme.token.colorPrimary+'88');
        document.body.style.setProperty('--colorPrimaryA', this.theme.token.colorPrimary+'aa');
        document.body.style.setProperty('--colorSuccess', this.theme.token.colorSuccess);
        document.body.style.setProperty('--colorSuccess2', this.theme.token.colorSuccess+'22');
        document.body.style.setProperty('--colorSuccess4', this.theme.token.colorSuccess+'44');
        document.body.style.setProperty('--colorSuccess8', this.theme.token.colorSuccess+'88');
        document.body.style.setProperty('--colorSuccessA', this.theme.token.colorSuccess+'aa');
        document.body.style.setProperty('--colorWarning', this.theme.token.colorWarning);
        document.body.style.setProperty('--colorWarning2', this.theme.token.colorWarning+'22');
        document.body.style.setProperty('--colorWarning4', this.theme.token.colorWarning+'44');
        document.body.style.setProperty('--colorWarning8', this.theme.token.colorWarning+'88');
        document.body.style.setProperty('--colorWarningA', this.theme.token.colorWarning+'aa');
        document.body.style.setProperty('--colorError', this.theme.token.colorError);
        document.body.style.setProperty('--colorError2', this.theme.token.colorError+'22');
        document.body.style.setProperty('--colorError4', this.theme.token.colorError+'44');
        document.body.style.setProperty('--colorError8', this.theme.token.colorError+'88');
        document.body.style.setProperty('--colorErrorA', this.theme.token.colorError+'aa');
        document.body.style.setProperty('--colorInfo', this.theme.token.colorInfo);
        document.body.style.setProperty('--colorInfo2', this.theme.token.colorInfo+'22');
        document.body.style.setProperty('--colorInfo4', this.theme.token.colorInfo+'44');
        document.body.style.setProperty('--colorInfo8', this.theme.token.colorInfo+'88');
        document.body.style.setProperty('--colorInfoA', this.theme.token.colorInfo+'aa');
        document.body.style.setProperty('--borderRadius', this.theme.token.borderRadius+"px");
        document.body.className="index-theme-"+mo.setting.theme;
	},
	fn:{
		getHash:function(){
			let hash=location.hash;
			if(hash.substring(0, 1)=='#') hash=hash.substring(1);
			return hash;
		},
		fillJSONData:function(data,name,value){
			let flag=true;
			let index=0;
			let arr=name.split("");
			for(let i=0;i<arr.length;i++){
				if(arr[i]=="[") flag=false;
				else if(arr[i]=="]") flag=true;
				if(flag&&arr[i]=="."){
					index=i;
					break;
				}
			}
			if(index>0){
				let f1=name.substring(0,index);
				let f2=name.substring(f1.length+1);
				if(f1.indexOf("[")>-1&&f1.indexOf("]")==f1.length-1){
					let nm=f1.substring(0,f1.indexOf("["));
					let ni=f1.substring(nm.length+1,f1.length-1);
					if(isNaN(ni)){
						if(!data[nm]) data[nm]={};
						mo.fn.fillJSONData(data[nm],ni+"."+f2,value);
					}else{
						if(!data[nm]) data[nm]=[];
						let n=parseInt(ni);
						for(let i=1;i<=n+1;i++){
							if(data[nm].length<i)data[nm].push({});
						}
						mo.fn.fillJSONData(data[nm][n],f2,value);
					}
				}else{
					if(!data[f1]) data[f1]={};
					mo.fn.fillJSONData(data[f1],f2,value);
				}
			}else{
				let f1=name;
				if(f1.indexOf("[")>-1&&f1.indexOf("]")==f1.length-1){
					let nm=f1.substring(0,f1.indexOf("["));
					let ni=f1.substring(nm.length+1,f1.length-1);
					if(isNaN(ni)){
						if(!data[nm]) data[nm]={};
						data[nm][ni]=value;
					}else{
						if(!data[nm]) data[nm]=[];
						if(!ni){
							data[nm]=value.split(',');
						}else{
							let n=parseInt(ni);
							for(let i=0;i<=n+1;i++){
								if(data[nm].length<i)data[nm].push(null);
							}
							data[nm][n]=value;
						}
					}
				}else{
					data[name]=value;
				}
			}
		},
		getJSONData:function(data,name){
			let flag=true;
			let index=0;
			let arr=name.split("");
			for(let i=0;i<arr.length;i++){
				if(arr[i]=="[") flag=false;
				else if(arr[i]=="]") flag=true;
				if(flag&&arr[i]=="."){
					index=i;
					break;
				}
			}
			if(index>0){
				let f1=name.substring(0,index);
				let f2=name.substring(f1.length+1);
				if(!data[f1]) data[f1]={};
				return mo.fn.getJSONData(data[f1],f2);
			}else{
				return data[name];
			}
		},
        urlEncode:function(param, key, encode) {
            if(param==null) return '';
            let paramStr = '';
            let t = typeof (param);
            if (t == 'string' || t == 'number' || t == 'boolean') {
                paramStr += '&' + key + '=' + ((encode==null||encode) ? encodeURIComponent(param) : param);
            } else {
                for (let i in param) {
                    let k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
                    paramStr += mo.fn.urlEncode(param[i], k, encode);
                }
            }
            return paramStr;
        },
        getUrlParams:function(url){
            if(url.indexOf("?")<0) return {};
            let paramStr=url.substring(url.indexOf("?")+1);
            let ps={};
            let arr = paramStr.split("&");
            for(let i = 0; i < arr.length; i ++) {
                let ns=arr[i];
                let n=ns.indexOf("=");
                this.fillJSONData(ps,ns.substring(0,n),ns.substring(n+1));
            }
            return ps;
        },
        //返回字典选项   返回字典选项
        fillDictOption:function(obj,type,fn){
            if(mo.dictOpts[type]&&(!mo.dictReload[type])){
                obj[type]=mo.dictOpts[type];
                if(fn) fn(obj[type]);
            }else if(mo.dictMap[type]){
                mo.dictReload[type]=false;
                let options=[];
                for(let k in mo.dictMap[type]){
                    let arr=mo.dictMap[type][k].split("|");
                    options.push({key:k,value:k,label:arr[0],disabled:arr[1]!="Y"});
                }
                mo.dictOpts[type]=options;
                mo.fn.fillDictOption(obj,type,fn);
            }
        },
        //返回字典树选项   返回字典选项
        fillDictTree:function(obj,type,fn){
            if(mo.dictTreeOpts[type]&&(!mo.dictReload[type])){
                obj[type]=mo.dictTreeOpts[type];
                if(fn) fn(obj[type]);
            }else if(mo.dictMap[type]){
                mo.dictReload[type]=false;
                let setTree=function(opts,k,arr){
                    for(let i=0;i<opts.length;i++){
                        let po=opts[i];
                        if(po.key==arr[2]){
                            po['selectable']=false;
                            po.children.push({key:k,value:k,title:arr[0],label:arr[0],disabled:arr[1]!="Y",children:[]});
                            return true;
                        }else{
                            if(setTree(po.children,k,arr)){
                                return true;
                            }
                        }
                    }
                    return false;
                };
                let options=[];
                let ls={};
                for(let k in mo.dictMap[type]){
                    let arr=mo.dictMap[type][k].split("|");
                    if(arr[2]){
                        ls[k]=arr;
                    }else{
                        options.push({key:k,value:k,title:arr[0],label:arr[0],disabled:arr[1]!="Y",children:[]});
                    }
                }
                let fillTree=function(){
                    let n=0;
                    for(let k in ls){
                        if(setTree(options,k,ls[k])){
                            n++;
                            delete ls[k];
                        }
                    }
                    if(n>0) fillTree();
                };
                fillTree();
                mo.dictTreeOpts[type]=options;
                mo.fn.fillDictTree(obj,type,fn);
            }
        },
	},
	mixin:{
		data:function(){
		    let k="v_"+new Date().getTime()+Math.floor(Math.random()*9999);
			return {
			    theme:mo.theme,localeZh:antd.locales.zh_CN,
				key:k,
				pageKey:'',thisPageUrl:'',
				ajaxNum:0,
				dictOpts:{},dictTreeOpts:{},dictLab:{},
				isBackFlag:false,isBackObj:null,
				openType:'',openWidth:'60%',openCallback:null,
				showModal:false,showPage:false,showDrawer:false,
				popoverShow:{},popoverLoad:{},popoverWidth:{},popoverCallback:{},
				pageLoadSpinning:false,
				prewImagePath:'',prewImageObj:{visible:false,onVisibleChange:this.prewImageVisible}
			}
		},
		methods:{
		    //四舍五入 d数字，n几位小数
		    roundNumber:function(d,n){
		        if(n<=0) return Math.round(d);
		        let m=1;
		        for(let i=0;i<n;i++) m*=10;
		        return Math.round(d * m)/m;
		    },
		    //数字格式化 d数字 f格式 #,##0.00
		    formatNumber:function(d,f){
		        return formatNumber(d,f);
		    },
		    //日期格式化 d日期 f格式 yyyy-MM-dd HH:mm:ss
		    formatDate:function(d,f){
		        return new Date(d).format(f);
		    },
		    formatShow:function(d,f){
		        return new Date(d).formatShow(f);
		    },
		    outTxt:function(obj){
		        if(null==obj) return "";
		        return obj+"";
		    },
		    //无参数限制，decode
		    decode:function(){
		        var arr=arguments;
                if(arr.length==0) return null;
                if(arr.length==1) return arr[0];
                if(arr.length==2) return arr[1];
                let i=1;
                for(;i<arr.length;i+=2){
                    if(arr[0]==arr[i]&&arr.length>i+1){
                        return arr[i+1];
                    }
                }
                if(i-arr.length==1) return arr[i-2];
                return null;
		    },
		    gap4Top:function(ele){
		        if(ele.getBoundingClientRect){
		            return ele.getBoundingClientRect().top;
		        }else{
                    let pg=ele;
                    let h=pg.offsetTop;
                    while(pg.offsetParent){
                        pg=pg.offsetParent;
                        h+=pg.offsetTop;
                    }
                    return h;
		        }
		    },
		    //提醒消息  type:success,error,info,warn  colorType:primary,success,error,info,warn
		    remind:function(type,msg,tt,colorType){
		        let fn=function(message,title){
                    let action='primary';
                    if('success'==type||'error'==type||'info'==type||'warn'==type){
                        action=type;
                    }
                    if(!colorType) colorType=action;
                    let option={
                        class:'index-notification-'+colorType,
                        message: title?title:message,
                        description:title?message:'',
                        placement:'top',
                        top:'80px',
                        duration:2.5
                    };
                    if("primary"==action){
                        option.icon=()=>Vue.h("div",{style:{marginTop:'20px'}},Vue.h(this['_'].appContext.components['m-icon'],{name:type,size:26,color:this.theme.token.colorPrimary}));
                        this.$notification['open'](option);
                    }else{
                        this.$notification[action](option);
                    }
		        }.bind(this);
		        if(type){
		            fn(msg,tt);
		        }else{
                    return {
                        success:function(m,t){type='success';fn(m,t);},
                        error:function(m,t){type='error';fn(m,t);},
                        info:function(m,t){type='info';fn(m,t);},
                        warn:function(m,t){type='warn';fn(m,t);}
                    };
		        }
		    },
			//请求
			requestData:function(url,params,fn,nomask,header){
				let flag=nomask?false:true;
				header=header||{};
				if(flag){
                    this.pageLoadSpinning=true;
                    this.ajaxNum++;
				}
				axios.post(url,params,{headers:header})
				.then(function(response) {
                    if(flag){
                        this.ajaxNum--;
                        if(this.ajaxNum==0) this.pageLoadSpinning=false;
					}
					fn(response.data);
				}.bind(this))
				.catch(function(error) {
				    this.ajaxNum--;
					if(this.ajaxNum==0) this.pageLoadSpinning=false;
					this.remind().error('请求错误');
					console.error(error);
					this.recordLog('页面错误','请求成功，但页面执行发生异常。',
					    url,params,{message:error.message,stack:error.stack},"异常");
				}.bind(this));
			},
			recordLog:function(title,description,path,readText,backText,status){
                axios.post("action/manage/actionLog/record",{model:{title:title,description:description,path:path,readText:readText,status:status,backText:backText}});
			},
			//初始化字典
			initDict:function(type){
			    if(mo.dictMap[type]) return mo.dictMap[type];
			    if(!mo.dictLoad[type]){
			        if(type.indexOf("action/")==0){//接口字典 返回DictionaryUtil.toDictData封装的数据
                        mo.dictLoad[type]=true;
                        this.requestData(type,
                        {},json=>{
                            if(json.code==0){
                                mo.dictMap[type]=json.map;
                            }
                        });
			        }else if(type.indexOf("@")==0){//例如：@A:111,B:222,C:333
                        let arr=type.substring(1).split(",");
                        let map={};
                        for(let i=0;i<arr.length;i++){
                            let strs=arr[i].split(":");
                            map[strs[0]]=strs[1]+'|Y|';
                        }
                        mo.dictMap[type]=map;
                    }else{//系统字典 or 字典类模型 or 字典属性
                        mo.dictLoad[type]=true;
                        this.requestData('action/manage/dictionaryType/getDict',
                        {model:{type:type}},json=>{
                            if(json.code==0){
                                mo.dictMap[type]=json.map;
                            }
                        });
                    }
			    }
                return false;
			},
			resetDict:function(type){
                mo.dictMap[type]=null;
                mo.dictLoad[type]=false;
                mo.dictReload[type]=true;
			    return this.initDict(type);
			},
			//返回字典选项   返回字典选项
			dictOptions:function(type,fn){
			    if(!this.dictOpts[type]) this.dictOpts[type]=[];
			    if(this.initDict(type)){
			        mo.fn.fillDictOption(this.dictOpts,type,fn);
			    }else{
			        setTimeout(()=>{
			            this.dictOptions(type,fn);
                    },100)
			    }
			    return this.dictOpts[type];
			},
			//返回字典树选项   返回字典选项
			dictTreeOptions:function(type,fn){
			    if(!this.dictTreeOpts[type]) this.dictTreeOpts[type]=[];
			    if(this.initDict(type)){
			        mo.fn.fillDictTree(this.dictTreeOpts,type,fn);
			    }else{
			        setTimeout(()=>{
			            this.dictTreeOptions(type,fn);
                    },100)
			    }
			    return this.dictTreeOpts[type];
			},
			//展示字典 类型，值，是否返回父值，是否返回父值名称
			dict:function(type,value,parent,parentName){
			    parent=parent||false;
			    parentName=parentName||false;
			    if(this.initDict(type)){
                    if(mo.dictMap[type]&&(value||value!=null||value!=undefined)){
                        let arr=value instanceof Array?value:(typeof(value)=='string'?value.split(","):[''+value]);
                        arr=arr.filter(function(item,index) {return arr.indexOf(item)===index;});
                        let ss=[];
                        for(let i=0;i<arr.length;i++){
                            if(mo.dictMap[type]&&arr[i]){
                                let s=mo.dictMap[type][arr[i]]?mo.dictMap[type][arr[i]].split("|")[parent?2:0]:arr[i];
                                ss.push(s);
                            }
                        }
                        if(parentName) this.dictLab[type+"-"+value+"-"+parent+parentName]=this.dict(type,""+ss,false);
                        else this.dictLab[type+"-"+value+"-"+parent+parentName]=""+ss;
                    }
                }
                return this.dictLab[type+"-"+value+"-"+parent+parentName]||(value&&value.length==0?"":value);
			},
			//新窗口打开
            openWindow:function(url){
                window.open('adminOpen#'+encodeURIComponent(url));
            },
			//加载页面  指定id对象加载页面
			loadPage:function(id,url,params,fn){
				console.log("loadPage: ",id,url,params);
				if(null==params) params={};
				params=deepMerge(params,mo.fn.getUrlParams(url));
				this.pageLoadSpinning=true;
				this.requestData(url, params, function(data) {
					this.pageLoadSpinning=false;
					let json=typeof(data)=='object'?data:(new Function("return "+data))();
					if(json.msg){
						this.remind().error(json.msg);
						this.backHandler(false);
					}else{
					    params.thisPageUrl=url;
					    this.loadTemp(id,json,params,fn);
					}
				}.bind(this),true);
			},
			//加载模板
			loadTemp:function(id,data,params,fn){
				if(null==params) params={};
				if(mo.pageV3s[id]) mo.pageV3s[id].unmount();
                let json=typeof(data)=='object'?data:(new Function("return "+data))();
                if(json.param){
                    params=deepMerge(params,json.param);
                    delete json.param;
                }
                json.template='<a-spin size="large" :delay="100" :spinning="pageLoadSpinning">'
                    +'<a-config-provider :locale="localeZh" :theme="theme">'
                        +'<div style="display:none;"><a-image :src="prewImagePath" :preview="prewImageObj" /></div>'
                        +'<transition name="pageShow"><div :id="\'PAGE_\'+key" style="width:100%;" v-if="showPage">'
                        +'<a-page-header title="加载中" sub-title="请稍后...">'
                            +'<template #extra><m-back @click="backHandler(false,null,true);">关闭</m-back></template>'
                        +'<a-skeleton active /></a-page-header>'
                        +'</div></transition>'
                        +'<transition name="pageShow"><div v-if="!showPage" style="width:100%;">'
                        +json.template
                        +'</div></transition>'
                    +'<a-modal :width="openWidth" v-model:open="showModal" :closable="false" :keyboard="false" :mask-closable="false" class="index-modal">'
                        +'<div v-if="showModal&&pageLoadSpinning">'
                        +'<a-page-header title="加载中" sub-title="请稍后...">'
                            +'<template #extra><m-back @click="backHandler(false,null,true);">关闭</m-back></template>'
                        +'<a-skeleton active /></a-page-header>'
                        +'</div>'
                        +'<div :id="\'MODAL_\'+key"></div></a-modal>'
                    +'<a-drawer :width="openWidth" v-model:open="showDrawer" :closable="false" :keyboard="false" :mask-closable="false" :rootClassName="'+"['index-drawer']"+'">'
                        +'<div v-if="showDrawer&&pageLoadSpinning">'
                        +'<a-page-header title="加载中" sub-title="请稍后...">'
                            +'<template #extra><m-back @click="backHandler(false,null,true);">关闭</m-back></template>'
                        +'<a-skeleton active /></a-page-header>'
                        +'</div>'
                        +'<div :id="\'DRAWER_\'+key"></div></a-drawer>'
                    +'</a-config-provider>'
                +'</a-spin>';
                let v3=Vue.createApp(json,{param:params,parentVue:this});
                v3.mixin(mo.mixin).use(antd).use(mo.component);
                mo.pageV3s[id]=v3;
                mo.pages[id]=v3.mount("#"+id);
                mo.pages[id].pageKey=id;
                mo.pages[id].thisPageUrl=params.thisPageUrl;
                if(fn) fn(mo.pages[id],v3);
			},
			//子页面退出方法 关闭当前打开的页面
			back:function(flag,obj){
			    console.log("back: ",flag,obj);
				this.parentVue.backHandler(this.isBackFlag||flag,this.isBackObj||obj);
			},
			//子页面不退出，预先设置退出参数
			setBack:function(flag,obj){
			    this.isBackFlag=flag;
			    this.isBackObj=obj;
			},
			//父页面接收退出参数并关闭子页面  该方法不能被覆盖
			backHandler:function(flag,obj,back){
			    if(back) this.pageLoadSpinning=false;
                if(this.openType.indexOf("POPOVER")==0){
                    if(flag) this.popoverLoad[this.openType]=false;
                    this.popoverShow[this.openType]=false;
                    if(this.popoverCallback[this.openType]){
                        this.popoverCallback[this.openType](flag,obj);
                        this.popoverCallback[this.openType]=null;
                        this.notify(flag,"openPage,"+this.openType,obj);
                    }
                }
                else if(this.openType=="MODAL"||this.openType=="PAGE"||this.openType=="DRAWER"){
                    if(this.openType=="MODAL") this.showModal=false;
                    else if(this.openType=='PAGE') this.showPage=false;
                    else if(this.openType=='DRAWER') this.showDrawer=false;
                    let ele=document.getElementById(this.openType+"_"+this.key);
                    if(ele&&ele.innerHTML){
                        setTimeout(()=>{
                            ele.innerHTML="";
                        },100);
                    }
                }
				if(this.openCallback){
					this.openCallback(flag,obj);
					this.openCallback=null;
                    this.notify(flag,"openPage,"+this.openType,obj);
				}
			},
			//打开页面 url地址，ps参数， callback页面关闭的回调方法，openWidth打开宽度，type打开类型，showMsg请求是否返回消息
			//type ：AJAX，POPOVER，MODAL，PAGE，DRAWER
			openPage:function(url,ps,callback,openWidth,type,showMsg){
				if(!ps)ps={};
				if(!type)type='MODAL';
				ps.isOpen=true;
				ps.openType=type;
				this.openType=type;
                if(type.indexOf("POPOVER")==0){
                    if(this.popoverLoad[type]) return;
                    this.popoverLoad[type]=true;
                    this.popoverWidth[type]=openWidth;
                    this.popoverCallback[type]=callback;
                    this.loadPage(type+"_"+this.key,url,ps);
                }else if(type=='MODAL'||type=='PAGE'||type=='DRAWER'){
					this.openWidth=openWidth;
					this.openCallback=callback;
					if(type=='MODAL') this.showModal=true;
					else if(type=='PAGE') this.showPage=true;
					else if(type=='DRAWER') this.showDrawer=true;
					this.loadPage(type+"_"+this.key,url,ps);
				}else if(type=="AJAX"){
					this.requestData(url,ps,(data)=>{
						if(data.code==0){
							if(data.msg)
								if(showMsg) this.remind().success(data.msg);
							callback(true,data);
				            this.notify(true,"openPage,"+type,data);
						}else{
							callback(false,data);
							if(showMsg) this.remind().error(data.msg);
				            this.notify(false,"openPage,"+type,data);
						}
					});
				}else if(type=="OPEN"||type=='WINDOW'){
				    let p=mo.fn.urlEncode(ps);
				    let u=url.indexOf('?')>0?(url+p):(url+'?'+p);
				    if(type=="WINDOW") this.openWindow(u);
				    else window.open(u);
				    callback(true,{});
                    this.notify(true,"openPage,"+type,{});
				}
			},
			//子页面向父页面发送通知
			notify:function(flag,type,obj){
			    console.log("notify: ",flag,type,obj,this.thisPageUrl);
			    try{
			        this.parentVue.notifyHandler(flag,type,obj,this.thisPageUrl);
			    }catch(e){
			        console.log("notify-error: ",e);
			    }
			},
			//父页面接收通知  当前页面需重写该方法才能接收到子页面的通知
			notifyHandler:function(flag,type,obj,url){
			    console.log("notifyHandler: ",flag,type,obj,url);
			},
			selectFilter:function(str,opt){//select组件:filter-option属性
				if(opt.label){
					return opt.label.indexOf(str)>=0;
				}else{
					return opt.children[0].children.indexOf(str)>=0;
				}
			},
			treeSelectFilter:function(str,opt){
				if(opt.title){
					return opt.title.indexOf(str)>=0;
				}else{
					return opt.children[0].children.indexOf(str)>=0;
				}
			},
			selectPopup:function(triggerNode){//select组件:getPopupContainer属性
				setTimeout(function(){
					let d=triggerNode.parentNode.lastElementChild;
					d.style.position='relative';
					d.firstElementChild.firstElementChild.style.position='relative';
					d.firstElementChild.firstElementChild.style.top='0px';
				},5);
				return triggerNode.parentNode;
			},
			prewImageVisible:function(visible, prevVisible){
				if(!visible) this.prewImageObj.visible=false;
			},
			//查看icon模型
			viewIcon:function(iconModel){
				if(iconModel&&iconModel.oid) {
					this.prewImagePath=iconModel.path;
					this.prewImageObj.visible=true;
				}
					//this.openPage('page/base/util/viewImage.js',{imgSrc:iconModel.path},(obj)=>{},'200px');
			},
			//查看image模型
			viewImage:function(imgModel){
				if(imgModel&&imgModel.oid){
					this.prewImagePath=imgModel.imgPath;
					this.prewImageObj.visible=true;
				}
					//this.openPage('page/base/util/viewImage.js',{imgSrc:imgModel.imgPath},(obj)=>{},'70%');
			},
			//查看图片地址
			viewImgPath:function(imgPath){
				if(imgPath){
					this.prewImagePath=imgPath;
					this.prewImageObj.visible=true;
				}
				//this.openPage('page/base/util/viewImage.js',{imgSrc:imgPath},(obj)=>{},'60%');
			},
			//选择图片  name 搜索图片名称
			selectImagePage:function(model,field,imageType,name){
				let selected='';
				if(model&&field&&model[field]&&model[field].oid){
					selected=model[field].oid;
				}
				this.openPage('action/manage/imageInfo/toSelectImage',{imageType:imageType,name:name,selected:selected},function(flag,obj){
					if(flag) model[field]=obj;
				},"1000px");
			},
			//选择icon
			selectIconPage:function(model,field,name,business){
				let selected='';
				if(model&&field&&model[field]&&model[field].oid){
					selected=model[field].oid;
				}
				this.openPage('page/base/util/selectIcon.js',{selected:selected,name:name,business:business},function(flag,obj){
					if(flag) model[field]=obj;
				},"1000px");
			},
			//选择icon class
			selectIconClass:function(model,field){
				let selected='';
				if(model&&field){
					selected=model[field];
				}
				this.openPage('page/base/util/selectIconClass.js',{selected:selected},function(flag,obj){
					if(flag) model[field]=obj;
				},"1000px");
			},
			//选择一个管理员
			selectOneAdmin:function(model,field,orgGroup,roleGroup,fn){
				let isArr=typeof(model[field])=='object'&&typeof(model[field].length)=='number';
				this.openPage('page/base/util/selectAdmin.js',
                    {selected:isArr?model[field]:[model[field]],isRadio:true,orgGroup:""+(orgGroup||""),roleGroup:""+(roleGroup||"")},
                    function(flag,obj){
                        if(flag){
                            if(isArr) model[field]=obj;
                            else model[field]=obj[0];
                        }
                        if(fn) fn(flag,obj);
                    },
                    "1000px"
				);
			},
			//选择多个管理员
			selectManyAdmin:function(model,field,orgGroup,roleGroup,fn){
				this.openPage('page/base/util/selectAdmin.js',
                    {selected:model[field],isRadio:false,orgGroup:""+(orgGroup||""),roleGroup:""+(roleGroup||"")},
                    function(flag,obj){
                        if(flag) model[field]=obj;
                        if(fn) fn(flag,obj);
                    },
                    "1000px"
				);
			},
			//选择JS页面
			selectJsPage:function(model,field,actionUrl,openWidth,type,fn){
				this.openPage(actionUrl,{},
                    function(flag,obj){
                        if(flag){
                            let isArr=typeof(obj)=='object'&&typeof(obj.length)=='number';
                            model[field]=isArr?obj[0]:obj;
                        }
                        if(fn) fn(flag,obj);
                    },
                    openWidth,type
				);
			},
			//打开单选列表页面
			selectOneModel:function(model,field,actionUrl,openWidth,type,fn){
				this.openPage(actionUrl,
                    {params:{selected:model[field].oid}},
                    function(flag,obj){
                        if(flag){
                            let isArr=typeof(obj)=='object'&&typeof(obj.length)=='number';
                            model[field]=isArr?obj[0]:obj;
                        }
                        if(fn) fn(flag,obj);
                    },
                    openWidth,type
				);
			},
			//打开多选列表页面
			selectManyModel:function(model,field,actionUrl,openWidth,type,fn){
				let isArr=typeof(model[field])=='object'&&typeof(model[field].length)=='number';
				let arr=isArr?model[field]:[model[field]];
				let oids="";
				for(let i=0;i<arr.length;i++){
				    if(i!=0) oids+=',';
				    oids+=arr[i].oid;
				}
				this.openPage(actionUrl,
                    {params:{selected:oids}},
                    function(flag,obj){
                        if(flag) model[field]=obj;
                        if(fn) fn(flag,obj);
                    },
                    openWidth,type
				);
			}
		}
	},
	vueResult:{
		methods:{
			formatter:function(type,cellValue,format){//格式化 date number
			    if(format){
			        if(cellValue=='小计'){
			            return '小计';
			        }else if(type=='date'||(format.indexOf('#')+format.indexOf('0')+format.indexOf('%')+2)<0){
                        if(cellValue) return new Date(cellValue).format(format);
                        else return "";
                    }else if(type=='number'||(format.indexOf('#')+format.indexOf('0')+format.indexOf('%')+2)>=0){
                        if(cellValue==0||cellValue) return formatNumber(cellValue,format);
                        else return "";
                    }
			    }
				return cellValue;
			}
		}
	},
	listResult:{
		methods:{
		    setSearchParams:function(){
				for(let k in this.inputParams){
				    if(k!='echarts_x'&&k!='echarts_y')
					    this.searchParams[k]=this.inputParams[k];
				}
		    },
		    threadResult:function(key,fn){
		        let method=this.dataUrl.substring(this.dataUrl.lastIndexOf("/")+1);
                let action=this.dataUrl.replace('action/','').replace('/'+method,'');
                axios.post('action/'+action+'/getThreadResult',
                    {threadKey:key}
                ).then((rs)=>{
                    let json=rs.data;
                    if(json.code==2) setTimeout(()=>{this.threadResult(key,fn);},2000);
                    else fn(json);
                }).catch(error=>{
                    console.error("threadResult",error)
                });
		    },
			excelData:function(){
			    this.downExcel=true;
				let qtime=new Date().getTime();
				let key="key"+new Date().getTime();
				this.setSearchParams();
				this.$notification.info({key:key,duration:0,message:'导出Excel中',description:'正在请求导出Excel，不要再次点击，请稍后...',placement:'bottomRight'});
				let method=this.dataUrl.substring(this.dataUrl.lastIndexOf("/")+1);
				let action=this.dataUrl.replace('action/','').replace('/'+method,'');
				let p={'method':method,order:this.order,params:this.searchParams,'columns':this.getColumnsParam()};
				this.notify(true,"listResult,excelData",p);
				let downError=(msg)=>{
                    this.downExcel=false;
                    this.$notification.error({key:key,message:'导出错误',description:'请联系管理员！'+msg,placement:'bottomRight'});
				};
				let downFn=(res)=>{
                    if(res.headers&&res.headers['content-disposition']){
                        this.downExcel=false;
                        this.$notification.success({key:key,message:'导出成功',description:'Excel导出成功，耗时'+formatNumber((new Date().getTime()-qtime)/1000,'#,##0.000')+'秒',placement:'bottomRight'});
                        let blob = new Blob([res.data]); //res为从后台返回的数据
                        let fileName = decodeURIComponent(res.headers['content-disposition'].split('filename=').pop());
                        if ('msSaveOrOpenBlob' in navigator) {
                            window.navigator.msSaveOrOpenBlob(blob, fileName);
                        } else {
                            const elink = document.createElement('a');
                            elink.download = fileName;
                            elink.style.display = 'none';
                            elink.href = URL.createObjectURL(blob);
                            document.body.appendChild(elink);
                            elink.click();
                            URL.revokeObjectURL(elink.href);
                            document.body.removeChild(elink);
                        }
                    }else{
                        let blob = new Blob([res.data]);
                        var reader = new FileReader();
                        reader.onload = ()=> {
                        	let json=JSON.parse(reader.result);
                        	if(json.code==2){
                                axios.post('action/'+action+'/getThreadResult',{threadKey:json.threadKey},
                                    {responseType: 'blob'}
                                ).then((rs)=>{
                                    setTimeout(()=>{downFn(rs);},2000);
                                });
                        	}else{
                        	    downError(json.msg);
                        	}
                        }
                        reader.readAsText(blob, 'utf8');
                    }
				};
				axios.post('action/'+action+'/exportExcel',
					p,
					{responseType: 'blob'}
				).then((res)=>{
				    downFn(res);
				}).catch(error=>{
                    downError(content);
					console.error(error)
				});
			},
			toEchartsPage:function(type){
				this.setSearchParams();
			    if(type) this.searchParams['echarts_type']=type;
				if(this.searchParams['echarts_x']&&this.searchParams['echarts_x'].length
				&&this.searchParams['echarts_y']&&this.searchParams['echarts_y'].length){
				    var width="75%";
				    if(this.searchParams['echarts_type']=='pie'){
				        if(this.searchParams['echarts_y'].length>3){
				            this.remind().error('数据选择不能超过3');
				            return;
				        }
				        if(this.searchParams['echarts_y'].length==1) width="450px";
				        if(this.searchParams['echarts_y'].length==2) width="850px";
				        if(this.searchParams['echarts_y'].length==3) width="1250px";
				    }
                    let method=this.dataUrl.substring(this.dataUrl.lastIndexOf("/")+1);
                    let action=this.dataUrl.replace('action/','').replace('/'+method,'');
                    let p={'method':method,order:this.order,params:this.searchParams};
				    this.notify(true,"listResult,echart",p);
				    let openChartFn=(data)=>{
				        if(data.msg){
				            this.remind().error(msg);
				        }else{
                            this.openPage('page/base/util/echarts.js',
                                {isOpen:true,option:data},
                                function(flag,obj){},
                                width
                            );
				        }
				    };
                    this.requestData('action/'+action+'/getEchartsData',p,(data)=>{
                        if(data.threadKey){
                            this.threadResult(data.threadKey,openChartFn);
                        }else{
                            openChartFn(data);
                        }
                    });
				}else{
				    this.remind().error('请选择查询内容');
				}
			},
			getColumnsParam:function(){
			    let str="";
			    for(let i=0;i<this.columnsSetting.length;i++){
			        let item=this.columnsSetting[i];
			        str+=item.title+"|"+item.show+","
			    }
			    return str;
			},
			setColumnsSort:function(idx,n){
                if(idx==0&&n==-1||idx==this.columnsSetting.length-1&&n==1) return;
                if(this.columnsSetting[idx+n].sort!='Y') return;
                let tmp=this.columnsSetting[idx];
                this.columnsSetting[idx]=this.columnsSetting[idx+n];
                this.columnsSetting[idx+n]=tmp;
			},
			queryData:function(index,pageSize,ps){//查询
				this.tableLoad=true;
				let qtime=new Date().getTime();
				this.setSearchParams();
				if(index) this.page.index=index;
				this.showView=false;
				this.popoverLoad={};
				let pg={index:(this.page.index-1)*this.page.num,num:this.page.num};
				if(ps) ps=deepMerge(ps,this.searchParams);
			    else ps=this.searchParams;
				let p={'queryData':'list','columnsParamKey':this.columnsParamKey,page:pg,order:this.order,params:ps};
				this.notify(true,"listResult,queryData",p);
                let listDone=false;
				let queryCountFn=(data)=>{
				    this.countLong=formatNumber((new Date().getTime()-qtime)/1000,'#,##0.000');
                    this.paginationLoad=false;
                    if(data.code==0){
                        this.tableSummary=data.summary;
                        this.tableSubtotal=data.subtotal;
                        this.tableSubfield=data.subfield;
                        this.tableCount=data.count;
                        this.querySuccessAfter(true);
                    }else{
                        this.remind().error(data.msg);
                    }
				};
				let queryListFn=(data)=>{
				    this.tableLoad=false;
					this.queryLong=formatNumber((new Date().getTime()-qtime)/1000,'#,##0.000');
					if(data.code==0){
					    let w=0;
						for(let i=0;i<data.columns.length;i++){
						    let col=data.columns[i];
							col.onFilterDropdownVisibleChange=this.hideResetInputParams;
							if(col.key==this.order.name){
								if(this.order.oper=='desc') col.sortOrder="descend";
								else if(this.order.oper=='asc') col.sortOrder="ascend";
							}
							if(this.colWidth[col.key]){
							    col.width=this.colWidth[col.key];
							}
							w+=col.width;
						}
						this.width=w;
						this.columnsSetting=data.columnsSetting;
						this.columns=data.columns;
						this.asMap=data.asMap;
						this.tableData=data.data;
						if(data.scol||data.scol==0) this.scol=data.scol;
						if(data.slength||data.slength==0) this.slength=data.slength;
                        if(!index||index==1){//首页
                            listDone=true;
                        }else{
						    this.querySuccessAfter(true);
                        }
                        if(this.setSelected){
                            for(let i=0;i<this.tableData.length;i++){
                                this.setSelected(i,this.tableData[i]);//选择
                            }
                        }
				        this.notify(true,"listResult,queryData,success",data);
				        this.autoSetBodyHeight();
					}else{
						this.remind().error(data.msg);
					}
				};
				let requestCountDone=false;
				let requestCountFn=()=>{
				    if(requestCountDone) return;
				    requestCountDone=true;
                    if(!index||index==1){//首页
                        this.paginationLoad=true;
                        this.requestData(this.dataUrl,{'queryData':'count','columnsParamKey':this.columnsParamKey,page:pg,order:this.order,params:this.searchParams},(data)=>{
                            let fn=()=>{
                                if(listDone){//列表查询完成后才执行汇总信息
                                    if(data.threadKey){
                                        this.threadResult(data.threadKey,queryCountFn);
                                    }else{
                                        queryCountFn(data);
                                    }
                                }else{
                                    setTimeout(fn,100);
                                }
                            };
                            fn();
                        },true);
                    }
				};
				let requestCountTimer=setTimeout(requestCountFn,1000);
                this.requestData(this.dataUrl,p,(data)=>{
                    if(data.threadKey){
                        this.threadResult(data.threadKey,queryListFn);
                    }else{
                        if(requestCountTimer) clearTimeout(requestCountTimer);
                        requestCountFn();
                        queryListFn(data);
                    }
				},true);
			},
			querySuccessAfter:function(insertSt){
			    //插入小计行
                if(insertSt&&this.tableSubfield&&this.tableData.length>1){
                    let getInsertRow=(lastRow)=>{
                        let insertRow={};
                        for(let k in this.tableSubtotal){
                            let stRow=this.tableSubtotal[k];
                            let f=true;
                            for(let n=0;n<this.columns.length;n++){
                                let col=this.columns[n];
                                if(this.tableSubfield==col.key) break;
                                if(lastRow[col.key]!=stRow[col.key]){
                                    f=false;
                                    break;
                                }
                            }
                            if(f){

                                insertRow=stRow;
                                break;
                            }
                        }
                        return insertRow;
                    };
                    let last=this.tableData[0];
                    let lastRow=0;
                    for(let i=1;i<this.tableData.length;i++){
                        let row=this.tableData[i];
                        let b=false;
                        for(let n=0;n<this.columns.length;n++){
                            let col=this.columns[n];
                            if(this.tableSubfield==col.key){
                                break;
                            }
                            if(last[col.key]!=row[col.key]){
                                b=true;
                                break;
                            }
                        }
                        if(b){
                            let insertRow=getInsertRow(last);
                            if(i-1!=lastRow){
                                this.tableData.splice(i,0,insertRow);
                                i++;
                            }
                            last=row;
                            lastRow=i;
                        }
                    }
                    if(this.tableData.length-1!=lastRow){
                        this.tableData.push(getInsertRow(last));
                    }
                }//插入小计行end
                this.$nextTick(function(){
                    if(this.tableData.length) this.mergeCells();
                    this.autoSetBodyHeight();
                }.bind(this));
			},
			autoSetBodyHeight:function(){
                if(this.height){
                    setTimeout(function(){
                        let he=this.height;
                        if(this.height<0){//小于0，则在负数的基础下自适应
                            let pg=this.$refs['vueListResultTable'].$el;
                            let h=this.gap4Top(pg);
                            he+=window.innerHeight-h-66;//66表格下方边距
                        }
                        //设置高度
                        let header=this.$refs['vueListResultTable'].$el.getElementsByClassName("ant-table-header")[0].clientHeight;
                        let summary=this.$refs['vueListResultTable'].$el.getElementsByClassName("ant-table-summary")[0].clientHeight;
                        this.bodyHeight=he-header-summary;
                    }.bind(this),300);
                }else{
                    this.bodyHeight=null;
                }
			},
			pageFocus:function(){
			    this.autoSetBodyHeight();
			    if(this.focusRefresh && !this.tableLoad){
			        this.queryData();
			    }
			},
			handleResizeColumn:function(w, col){
			    col.width = w;
			    this.colWidth[col.key]=w;
			},
			hideResetInputParams:function(v){
				if(!v) this.resetInputParams(true);
			},
			resetInputParams:function(isTime){
				let fn=function(){
					for(let k in this.searchParams){
						this.inputParams[k]=this.searchParams[k];
					}
				}.bind(this);
				if(isTime) setTimeout(fn,100);
				else fn();
			},
			mergeCells:function(){
				let tbody=this.$refs['vueListResultTable'].$el.getElementsByTagName("tbody")[0];
                for(let j=0;j<tbody.rows.length;j++){
                    for(let i=0;i<tbody.rows[j].cells.length;i++){
                        tbody.rows[j].cells[i].style.display="";
                        tbody.rows[j].cells[i].rowSpan=1;
                    }
                }
				let scol=this.scol+(this.selectField?1:0);
				let slength=this.slength;
				let isCount=false;
				let span_data=[];
				let sd_ti=0;
				if(tbody.rows.length>1){
					for(let i=scol;i<scol+slength;i++){
						span_data.push([]);
						let lastValue="|||||";
						for(let j=0;j<tbody.rows.length-(isCount?1:0);j++){
							if((i==scol || i>scol && span_data[i-scol-1][j])
								&& lastValue==tbody.rows[j].cells[i].innerHTML){
								span_data[sd_ti][j]=true;
							}else{
								span_data[sd_ti][j]=false;
								lastValue=tbody.rows[j].cells[i].innerHTML;
							}
							tbody.rows[j].cells[i].style.display="";
							tbody.rows[j].cells[i].rowSpan=1;
						}
						sd_ti++;
					}
					for(let i=span_data.length-1;i>=0;i--){
						let num=1;
						let tmp=null;
						for(let j=0;j<span_data[i].length;j++){
							if(span_data[i][j]){
								tbody.rows[j].cells[i+scol].style.display="none";
								num++;
							}else{
								if(tmp){
									tmp.rowSpan=num;
								}
								num=1;
								tmp=tbody.rows[j].cells[i+scol];
							}
						}
						if(tmp){
							tmp.rowSpan=num;
						}
					}
				}
			},
			isHasSearch:function(field){//是否有过滤值
				if(null!=this.searchParams[field]&&''+this.searchParams[field]
					||null!=this.searchParams[field+'_up']&&''+this.searchParams[field+'_up']
					||null!=this.searchParams[field+'_down']&&''+this.searchParams[field+'_down']){
					return true;
				}else{
					return false;
				}
			},
			tableChange:function(pagination, filters, sorter, { currentDataSource }){//排序
				if(sorter.order){
					this.order={name:sorter.columnKey,oper:sorter.order=='descend'?'desc':'asc'};
				}else{
					this.order={};
				}
				this.queryData();
			},
			filterHandle:function(selectedKeys, col){//筛选查询
				this.queryData(1);
			},
			resetHandle:function(col){//筛选重置
				if(null!=this.searchParams[col.key]&&''+this.searchParams[col.key]){
					if(typeof this.searchParams[col.key]=='string') this.searchParams[col.key]="";
					else this.searchParams[col.key]=[];
				}
				if(null!=this.searchParams[col.key+'_up']&&''+this.searchParams[col.key+'_up']) this.searchParams[col.key+'_up']="";
				if(null!=this.searchParams[col.key+'_down']&&''+this.searchParams[col.key+'_down']) this.searchParams[col.key+'_down']="";
				if(null!=this.searchParams[col.key+'_not']&&''+this.searchParams[col.key+'_not']) this.searchParams[col.key+'_not']=false;
				this.resetInputParams(false);
				this.queryData(1);
			},
			resetSearchField:function(fields){//重置按钮
			    for(let i=0;i<fields.length;i++){
			        let key=fields[i];
                    if(null!=this.searchParams[key]&&''+this.searchParams[key]){
                        if(typeof this.searchParams[key]=='string') this.searchParams[key]="";
                        else this.searchParams[key]=[];
                    }
                    if(null!=this.searchParams[key+'_up']&&''+this.searchParams[key+'_up']) this.searchParams[key+'_up']="";
                    if(null!=this.searchParams[key+'_down']&&''+this.searchParams[key+'_down']) this.searchParams[key+'_down']="";
				    if(null!=this.searchParams[key+'_not']&&''+this.searchParams[key+'_not']) this.searchParams[key+'_not']=false;
                    this.resetInputParams(false);
			    }
			},
			listEvent:function(record,obj,index,e){//列表事件
			console.log("list:event:",record,obj,index,e)
				if(obj.type.indexOf('POPOVER')==0){
				    obj.type=obj.type+index;
				    if(!e) return;
				}
				let self=this;
				let setField=function(putObj,param,getObj){
					if(param.name){
						if(param.field){
						    if(self.asMap[param.field]) param.field=self.asMap[param.field];
							mo.fn.fillJSONData(putObj,param.name,getObj[param.field]||mo.fn.getJSONData(getObj,param.field));
						}else if(param.value){
							mo.fn.fillJSONData(putObj,param.name,param.value);
						}else{
							mo.fn.fillJSONData(putObj,param.name,getObj);
						}
						return putObj;
					}else{
						if(param.field){
						    if(self.asMap[param.field]) param.field=self.asMap[param.field];
							return mo.fn.getJSONData(getObj,param.field);
						}else if(param.value){
							return param.value;
						}else{
							return getObj;
						}
					}
				};
				let ps={};
				for(let n=0;n<obj.queryParams.length;n++){//查询条件参数插入
					ps=setField(ps,obj.queryParams[n],this.searchParams);
				}
				let exeAfter=function(flag){//执行成功后
					if(flag&&obj.success=='REFRESH'||obj.success=='MUST_REFRESH'){
						this.queryData();
					}
				}.bind(this);
				let setData=function(rec,data){//行参数插入
					for(let n=0;n<obj.params.length;n++){
						data=setField(data,obj.params[n],rec);
					}
					return data;
				}.bind(this);
				if(record){//单选
					ps=setData(record,ps);
					if(obj.type=='BACK'){
					    this.back(true,ps);
					}else if(obj.type=='NOTIFY'){
				        this.notify(true,"listResult,listEvent,"+obj.type,ps);
					}else{
				        this.notify(true,"listResult,listEvent,"+obj.type,ps);
                        this.openPage(obj.url,ps,(flag,dd)=>{
                            exeAfter(flag);
                        },obj.openWidth,obj.type,true);
					}
				}else if(obj.type!='AJAX'){//多选 非ajax
					let list=[];
					let selectedKeys=this.selectedRowKeys||[];
					if(obj.params.length>0&&selectedKeys.length>0){
						for(let i=0;i<selectedKeys.length;i++){
						    let da={};
						    da=setData(this.selectedRowObjs[selectedKeys[i]],da);
						    list.push(da);
						}
					}else if(obj.params.length==0){
					}else{
						this.remind().error("请选择列表记录");
						return;
					}
					ps['list']=list;
					if(obj.type=='BACK'){
					    this.back(true,list);
					}else if(obj.type=='NOTIFY'){
				        this.notify(true,"listResult,listEvent,"+obj.type,ps);
					}else{
				        this.notify(true,"listResult,listEvent,"+obj.type,ps);
                        this.openPage(obj.url,ps,(flag,dd)=>{
                            exeAfter(flag);
                        },obj.openWidth,obj.type,true);
					}
				}else{//多选 ajax
					if(obj.params.length>0&&this.selectedRowKeys.length>0){
						let success=0,error=0,es="",sum=this.selectedRowKeys.length;
						let infoModal=this.$info({title:"任务执行中...",class:"no-modal",keyboard:false});
						let fnc=function(oid){
							let record=this.selectedRowObjs[oid];
							setData(record,ps);
				            this.notify(true,"listResult,listEvent,"+obj.type,ps);
							this.openPage(obj.url,ps,(flag,dd)=>{
								if(flag) success++; else error++;
								if(!flag&&dd.msg) es+="<br/>"+dd.msg;
								this.selectedRowKeys.remove(oid);
								delete this.selectedRowObjs[oid];
								if(this.selectedRowKeys.length>0){
									infoModal.update({
										title:Vue.h("div",{},["任务执行中..."+formatNumber((1-this.selectedRowKeys.length/sum)*100,"0")+"%"]),
										content:Vue.h("div",{style:'max-height:500px;overflow:auto;',innerHTML:"执行成功"+success+"条"+(error?("；失败"+error+"条。"):"")+es})
									});
									fnc(this.selectedRowKeys[0]);
								}else{
									infoModal.update({
										class:"",title:"执行成功"+success+"条"+(error?("；失败"+error+"条。"):""),
										content:Vue.h("div",{style:'max-height:500px;overflow:auto;',innerHTML:es?es.substr(5):''}),
										class:"yes-modal"
									});
									exeAfter(true);
								}
							},obj.openWidth,obj.type);
						}.bind(this);
						fnc(this.selectedRowKeys[0]);
					}else if(obj.params.length==0){
                        this.notify(true,"listResult,listEvent,"+obj.type,ps);
                        this.openPage(obj.url,ps,(flag,dd)=>{
                            if(dd.code==0) this.remind().success(dd.msg);
                            else this.remind().error(dd.msg);
                            exeAfter(flag);
                        },obj.openWidth,obj.type);
                    }else{
						this.remind().error("请选择要处理的记录");
					}
				}
			}
		}
	},
	component:{
		install:function(ap,obj){//自定义组件
		    //图标组件 <m-icon :name="module.icon" :size="19"></m-icon>
		    ap.component('m-icon',{
		        template:`<div style="display:inline-block;" :style="{marginTop:size1>16?'':'-3px',verticalAlign:size>16?'':'middle'}">
                	<template v-if="block">
                        <div style="display:block;padding-top:4px;text-align:center;" :style="{borderRadius:'var(--borderRadius)',width:(size1+4)+'px',height:(size1+4)+'px',background:backgroundColor1}">
                            <span class="iconfont" :class="name" :style="{fontSize:(size1-4)+'px',lineHeight:(size1-4)+'px',display:'block',color:'#fff'}"></span>
                        </div>
                	</template>
                	<template v-else>
                        <span class="iconfont" :class="name" :style="{marginLeft:'2px',fontSize:size1+'px',marginRight:'1px',color:'#0005',filter:'blur('+(size1/32)+'px)'}"></span>
                        <div style="display:inline-block;" :style="{marginLeft:-(size1+2)+'px'}">
                            <span class="iconfont" :class="name" :style="{fontSize:(size1+2)+'px',color:color1}"></span>
                        </div>
		            </template>
		        </div>`,
		        props:['name','color','size','block'],
		        computed:{
		            size1:function(){
                        if(this.size) return parseInt(this.size);
                        return 16;
		            },
		            color1:function(){
		                if(this.color) return this.color;
		                return '';
		            },
		            backgroundColor1:function(){
		                if(this.color) return 'linear-gradient('+this.color+'60,'+this.color+')';
		                return 'linear-gradient(var(--colorInfoA),var(--colorPrimary))';
		            }
		        }
		    });
		    //返回按钮  <m-back @click="back(false);">关闭</m-back>
		    ap.component('m-back',{
		        template:`<a-button :size="size" type="link" class="index-back-btn" style="font-weight:600;"><slot></slot><m-icon name="icon-icon-57"></m-icon></a-button>`,
		        props:['size']
		    });
		    //选择树组件 <select-tree v-model:value="link.toOrg" dict="manage.model.AdminGroup:C" parent multiple placeholder="请选择可选机构" />
		    ap.component('select-tree',{
                template:`<a-tree-select v-model:value="selectValue" :tree-data="selectItem" :placeholder="placeholder" :size="size" :disabled="disabled" :multiple="multiple" show-arrow show-search :filterTreeNode="treeSelectFilter"/>`,
                props:['value','dict','parent','multiple','placeholder','size','disabled'],
                emits: ['update:value'],
                data(){return {selectValue:'',selectItem:[]};},
                watch:{selectValue(newValue,oldValue){this.$emit('update:value', newValue);},
                    value(newValue,oldValue){this.selectValue=newValue;},
                    dict(newValue,oldValue){this.setItem();},
                },
                created(){
                    this.selectValue=this.value;
                    this.setItem();
                },
                methods:{
                    setItem:function(){
                        this.dictTreeOptions(this.dict,(st)=>{
                            if(this['parent']||this['parent']==''){
                                st=JSON.parse(JSON.stringify(st));
                                this.setSelectable(st);
                            }
                            this.selectItem=st;
                        });
                    },
                    setSelectable:function(arr){
                        for(let i=0;i<arr.length;i++){
                            let obj=arr[i];
                            if(!obj.selectable) obj.selectable=true;
                            if(obj.children&&obj.children.length){
                                this.setSelectable(obj.children);
                            }
                        }
                    }
                }
		    });
		    //选择项组件 <select-item v-model:value="link.toRole" dict="manage.model.AdminGroup:B" multiple placeholder="请选择角色" />
		    ap.component('select-item',{
                template:`<a-select v-model:value="selectValue" :options="selectItem" :placeholder="placeholder" :size="size" :disabled="disabled" :mode="modeStr" show-arrow show-search :filter-option="selectFilter"/>`,
                props:['value','dict','multiple','placeholder','size','disabled'],
                emits: ['update:value'],
                data(){return {selectValue:'',selectItem:[],modeStr:''};},
                watch:{selectValue(newValue,oldValue){this.$emit('update:value', newValue);},
                    value(newValue,oldValue){this.selectValue=newValue;},
                    dict(newValue,oldValue){this.setItem();},
                },
                created(){
                    this.selectValue=this.value;
                    this.modeStr=this['multiple']||this['multiple']==''?'multiple':'combobox';
                    this.setItem();
                },
                methods:{
                    setItem:function(){
                        this.dictOptions(this.dict,(st)=>{
                            this.selectItem=st;
                        });
                    }
                }
		    });
			ap.component('json-key',{
				template: `<span class="key">
				    <span v-html="pad"></span><span class="json_key" v-if="render">"{{jsonKey}}"</span><template v-if="render">:</template></span>`,
				props: ['json-key','type', 'current-depth'],
				computed: {
                    pad: function () {
                        return new Array(this.currentDepth+1).join(padstr);
                    },
                    render: function () {
                        return this.type!='Array';
                    }
				},
			});
			ap.component('json-val',{
				template: `<span class="val">
                    <template v-if="canToggle">
                        <template v-if="open">
                            <template v-if="type === 'Array'"><m-icon name="icon-moreunfold" @click="toggle"></m-icon> [<br/>
                                <json-item class="item" :json-val="jsonVal" :current-depth="currentDepth+1" :max-depth="maxDepth"></json-item><span v-html="pad"></span>]<template v-if="!last">,</template><br/>
                            </template>
                            <template v-else-if="type === 'Object'"><m-icon name="icon-moreunfold" @click="toggle"></m-icon> {<br/>
                                <json-item class="item" :json-val="jsonVal" :current-depth="currentDepth+1" :max-depth="maxDepth"></json-item><span v-html="pad"></span>}<template v-if="!last">,</template><br/>
                            </template>
                            </template>
                            <template v-else>
                            <template v-if="type === 'Array'">
                                <span @click="toggle"><m-icon name="icon-more"></m-icon> <span class="json_hide">Array[<span class="json_number">{{jsonVal.length}}</span>]</span></span><template v-if="!last">,</template><br/>
                            </template>
                            <template v-else-if="type === 'Object'">
                                <span @click="toggle"><m-icon name="icon-more"></m-icon> <span class="json_hide">Object{<span class="json_string">...</span>}</span></span><template v-if="!last">,</template><br/>
                            </template>
                        </template>
                    </template>
                    <template v-else>
                        <template v-if="type === 'Null'">
                            <span class="json_null">null</span><template v-if="!last">,</template><br/>
                        </template>
                        <template v-else-if="type === 'String'">
                            <span class="json_string">"{{jsonVal}}"</span><template v-if="!last">,</template><br/>
                        </template>
                        <template v-else-if="type === 'Number'">
                            <span class="json_number">{{jsonVal}}</span><template v-if="!last">,</template><br/>
                        </template>
                        <template v-else-if="type === 'Boolean'">
                            <span class="json_boolean">{{jsonVal ? 'true' : 'false'}}</span><template v-if="!last">,</template><br/>
                        </template>
                    </template>
				</span>`,
				props: ['json-val', 'current-depth', 'max-depth', 'last'],
				data: function () {
				    return { open: this.currentDepth < this.maxDepth };
				},
				computed: {
                    pad: function () {
                        return new Array(this.currentDepth+1).join(padstr);
                    },
                    type: function () {
                        return valueType(this.jsonVal);
                    },
                    canToggle: function () {
                        return this.type === 'Array' || this.type === 'Object';
                    }
				},
				methods: {
                    toggle: function () {
                        this.open = !this.open;
                    }
				}
			});
			ap.component('json-item',{
				template: `<span>
                    <template v-for="(key, i) in keys">
                        <json-key :json-key="key" :type="type" :current-depth="currentDepth"></json-key>
                        <json-val :last="i === keys.length-1" :json-val="jsonVal[key]" :current-depth="currentDepth" :max-depth="maxDepth"></json-val>
                    </template>
				</span>`,
				props: ['json-key', 'json-val', 'current-depth', 'max-depth'],
				computed: {
                    pad: function () {
                        return new Array(this.currentDepth).join(padstr);
                    },
                    type: function () {
                        return valueType(this.jsonVal);
                    },
                    keys: function () {
                        return Object.keys(this.jsonVal);
                    }
				}
			});
		}
	}
};
//////////json格式化
var padstr = '&nbsp;&nbsp;&nbsp;&nbsp;';
function valueType(value) {
    let tf = typeof value;
    let ts = Object.prototype.toString.call(value);
    return value === null ? 'Null' :
        'boolean' === tf ? 'Boolean' :
        'number' === tf ? 'Number' :
        'string' === tf ? 'String' :
        '[object Array]' === ts ? 'Array' : 'Object';
}
for(let k in mo.vueResult.methods){
	mo.listResult.methods[k]=mo.vueResult.methods[k];
}

